home *** CD-ROM | disk | FTP | other *** search
- /* reAdobe.c 1.1
- *
- * Copyright 1990, 1991 by Rob Elliott. All rights reserved.
- * Source code and executables may be freely distributed with the
- * copyright notice intact.
- *
- * Converts a type 1 font in text format (as used on NeXT computers,
- * for example ) into a Macintosh downloadable Type 1 font using
- * a resource fork format. By default, ".res" is appended to the
- * original filename.
- *
- * Developed with THINK C version 4.0. Contact me if you want to
- * help spruce this up. I envision a general purpose font converter,
- * also converting from binary -> text (currently done by the unAdobe
- * utility written elsewhere), as well as converting Type 1 -> Type 3
- * and supporting the MS-DOS file format.
- *
- * References:
- * _Supporting Downloadable Postscript(R in a Circle) Fonts_
- * Technical Note #5040 by Adobe Systems Incorporated. This
- * is available from their mail server on Internet, or through
- * the Developer support group.
- *
- * _Adobe Type 1 Font Format_, the "black book" by Adobe.
- *
- * Rob Elliott
- * Compuserve: 70675,1204
- * Internet: relliott@b11.ingr.com
- * 1030 Bayshore Drive #711, Huntsville, AL 35824
- *
- */
-
- #include <stdio.h>
- #define nil NULL
- /*#define DEBUG*/
-
- #define ASCIIDATA '\001'
- #define HEXDATA '\002'
- #define ENDOFFILE '\003'
- #define ENDOFFONT '\005'
-
- /* Prototypes */
- int htoi(char *s);
- int getinfile(Str255 filename);
- int getoutfile(Str255 filename);
- OSErr input(char *c);
- int output(char c,char resnum);
- int writeres(char resnum);
- void initbuf(void);
- void cvt(void);
- void resumeProc(void);
- void main(int argc, char *argv[]);
-
- /* Globals */
- #define INBUFMAX 1024 /* ideal maximum size of input buffer */
- unsigned char *inbuf; /* input buffer 1024 characters */
- unsigned int inptr; /* 0..1023 offset to current character */
- unsigned long inbufsize; /* working size of input buffer */
- int infilenum; /* input refnum */
-
- #define OUTBUFMAX 2046 /* ideal maximum size of output buffer */
- unsigned char *outbuf; /* output buffer 2046 characters */
- unsigned int outptr; /* 0..2045 offset to current character */
- unsigned long outbufsize; /* working size of output buffer */
- int outfilenum; /* output refnum */
-
- int theID; /* Resource ID (output) */
-
- /* hex (in string) to integer */
- int htoi(char *s)
- {
- register int i, n;
- register char h, hh;
-
- n = 0;
- for (i=0;
- (h = (s[i]>='0' && s[i]<='9'))
- || (hh = (s[i] >= 'a' && s[i] <= 'h'))
- || (s[i] >= 'A' && s[i] <= 'H');
- ++i)
- if (h)
- n = 16 * n + (s[i] - '0');
- else if (hh)
- n = 16 * n + (s[i] - 'a' + 10);
- else
- n = 16 * n + (s[i] - 'A' + 10);
- return n;
- }
-
- /* Get input filename via Std File */
- /* returns refnum of opened file */
- int getinfile(Str255 filename)
- {
- Point where;
- SFReply reply;
- int refnum;
- OSErr err;
-
- where.v = 55;
- where.h = 100;
-
- SFGetFile(where,"\pInput",nil,-1,nil,nil,&reply);
- if (reply.good) {
- err = FSOpen(reply.fName,reply.vRefNum,&refnum);
- if (err == noErr) {
- sprintf(filename,"%s.res",PtoCstr(reply.fName));
- return refnum; /* return refNum (assume nonzero) */
- }
- else {
- printf("Error opening input file: #%d\n",err);
- return 0;
- }
- }
- else {
- printf("Error getting file: #%d\n",err);
- return 0;
- }
- }
-
- /* Open output file as resource file */
- /* return refnum of resource */
- int getoutfile(Str255 filename)
- {
- Point where;
- SFReply reply;
- int refnum;
- OSErr err;
- OSType creator, type;
-
- where.v = 55;
- where.h = 100;
-
- SFPutFile(where,"\pOutput",CtoPstr(filename),nil,&reply);
- if (reply.good) {
- creator = 'ASPF';
- type = 'LWFN';
- err = Create(reply.fName,reply.vRefNum,creator,type);
- if ((err == dupFNErr)
- && (FSDelete(reply.fName,reply.vRefNum) != noErr)) {
- printf("Error overwriting output file\n");
- return(0);
- }
- if (err == noErr) {
- SetVol(nil,reply.vRefNum);
- CreateResFile(reply.fName);
- refnum = OpenResFile(reply.fName);
- if (refnum == -1) {
- return(0);
- }
- else return (refnum);
- }
- else {
- printf("Error creating output file: #%d\n",err);
- return 0;
- }
- }
- else {
- printf("Error getting output file: #%d\n",err);
- return 0;
- }
- }
-
- /* Allocate buffers */
- /* inbuf should be indexed 0..1023 */
- /* outbuf should be indexed 0..2045 */
- void initbuf()
- {
- inbufsize = INBUFMAX;
- inbuf = (unsigned char *) NewPtr(sizeof(unsigned char) * (inbufsize));
- inptr = inbufsize; /* force read from disk on first input() */
-
- outbufsize = OUTBUFMAX;
- outbuf = (unsigned char *) NewPtr(sizeof(unsigned char) * (outbufsize));
- outptr = 0;
-
- theID = 501; /* first/lowest POST resource number */
- return;
- }
-
- /* input
- get the next sequential input character from the input buffer
- if the buffer is exhausted, refill it from disk
- returned in argument ... eofErr or noErr will be function value
- */
- OSErr input(char *c)
- {
- long count; /* size (to be) read in from infile */
- OSErr err = noErr;
-
- /* inptr is 0..1023 */
- if (inptr == inbufsize) { /* reached end of buffer */
- if (inbufsize != INBUFMAX) { /* which was not a full buffer */
- return(eofErr);
- }
- else {
- /* Read a clump of input data */
- inbufsize = INBUFMAX;
- err = FSRead(infilenum,&inbufsize,inbuf); /* ? eofErr, noErr */
- if ((err == eofErr) && (inbufsize > 0))
- err = noErr; /* no real eofErr until buffer empty */
- inptr = 0;
- printf("Read %ld bytes\n",inbufsize);
- }
- }
- *c = inbuf[inptr++];
- return err;
- }
-
- /* output - add a character to the output buffer
- if buffer fills up, output a text resource
- returned in argument ... eofErr or noErr will be function value */
- int output(char c, char resnum)
- {
- long count; /* size (to) read in from infile */
- int err;
-
- /* outptr is 0..2045 - when it hits 2046, flush the buffer */
- if (outptr == outbufsize) {
- err = writeres(resnum);
- outptr = 0;
- outbuf[outptr++] = c;
- return(err);
- }
- else {
- outbuf[outptr++] = c;
- return noErr;
- }
- }
-
- /* writeres (char resnum)
- write the output buffer as a resource of type resnum
- reset the output buffer
- update the (next) output resource number
- */
- int writeres(char resnum)
- {
- ResType thetype;
- char **newres;
- char *masterptr;
- int i;
-
- /* outptr is 2046 in full case (one past last written index) */
- /* let new res be 2048 bytes long */
- newres = NewHandle(outptr+2); /* outptr already points 1 past end */
-
- HLock(newres); /* get a pointer to the new block */
- masterptr = *newres;
-
- masterptr[0] = resnum; /* first byte in resource defines the type */
- masterptr[1] = '\000'; /* always seems to be a null here */
- for (i=0; i < outptr; i++) {
- masterptr[i+2] = outbuf[i];
- }
- HUnlock(newres); /* new block is created */
-
- thetype = 'POST';
- AddResource(newres,thetype,theID,"\p");
- if (ResError() == addResFailed)
- return(addResFailed);
- WriteResource(newres);
- printf("Wrote resource %d\n",theID);
- theID++;
- return;
- }
-
- /* cvt text font file into resource font file
-
- algorithm:
- initialize buffers
- read ascii data until 'eexec', copying into POST resources of type 1
- read eexec data until 512 zeros, converting to binary and
- copying into POST resources of type 2
- read ascii data until eof (starting with the first zero), copying
- into a POST resource type 1
- output a POST resource type 5 (End of font program)
- */
- void cvt()
- {
- ResType thetype; /* resource type */
- int theID; /* resource ID */
- char c,d;
- int match; /* number of characters that match pattern */
- char outtwo[3] = "\000\000\000"; /* third byte is an end for htoi */
- int i,notfirsttime;
- char outc;
- OSErr err;
-
- initbuf();
- match = 0;
-
- while ((match < 6) && (input(&c) != eofErr)) {
- if (((match == 0) && (c == 'e'))
- || ((match == 1) && (c == 'e'))
- || ((match == 2) && (c == 'x'))
- || ((match == 3) && (c == 'e'))
- || ((match == 4) && (c == 'c'))
- || ((match == 5) && ((c == '\r') || (c == '\n')))) {
- match++;
- /*printf("+");*/ /* for debug */
- }
- else {
- match = 0; /* not a complete match */
- }
- output(c,ASCIIDATA);
- /*if (c == '\r') printf("\n"); /* for debugging *
- else
- printf("%c",c);*/
- }
- printf("eexec found\n");
- writeres(ASCIIDATA); /* flush type 1 resource */
- outptr=0;
-
- printf("----ascii parts finished-----");
-
- /* ASCII parts written, now write binary data until 512 zeros */
- /* reset input file to the start of binary data */
- err = SetFPos(infilenum,fsFromMark,(long) ( - (inbufsize - inptr)));
- /* reset input buffer - want to read in from file again */
- inptr = inbufsize;
-
- i=0;
- match = 0; /* number of 00s in a row */
-
- /* "512 zeros" is really 256 zeros in binary */
- while ((match < 256) && (input(&c) != eofErr)) {
- /*printf("%c",c);*/
- if (isspace(c)) /* skip over whitespace */
- continue;
- else if ((c == '0') && (i == 0)) { /* input is 0. */
- input(&d);
- if (d == '0') {
- match++;
- }
- else {
- if (match > 0) { /* we had 00s before */
- for (; match > 0; --match) output('\000',HEXDATA);
- }
- outtwo[0]='0';
- outtwo[1]=d;
- outc = htoi(outtwo);
- output(outc,HEXDATA);
- }
- }
- else {
- if (match > 0) { /* input not zero, but we had 00 before */
- for (; match > 0; --match) output('\000',HEXDATA);
- }
- if (i == 0)
- outtwo[i++] = c; /* 'c.' i=1 */
- else {
- outtwo[i--] = c; /* 'cc' i=0 */
- outc = htoi(outtwo);
- output(outc,HEXDATA);
- }
- }
- } /* while */
-
- /* 512 zeros found (or eof) */
- writeres(HEXDATA);
- printf("-----Hex data finished-----\n");
- outptr=0;
-
- for (match=0;match < 8;++match) {
- for (i=0; i < 64; ++i) output('0',ASCIIDATA);
- output('\r',ASCIIDATA);
- }
- sprintf(inbuf,"cleartomark\n");
-
- for (i=0; i < 12; ++i)
- output(inbuf[i],ASCIIDATA);
-
- writeres(ASCIIDATA);
- printf("-----Ascii 0000 data finished-----\n");
-
- outptr=0;
- writeres(ENDOFFONT);
- }
-
- void resumeProc ()
- {
- }
-
- void main(int argc, char *argv[])
- {
- Str255 filename;
-
- /* Standard Initialization Stuff */
- InitGraf(&thePort);
- InitFonts();
- FlushEvents(everyEvent,0);
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(&resumeProc);
- InitCursor();
-
- for (;;) {
- printf("reAdobe 1.1: Type 1 Font text -> resource format converter\n");
- printf("Copyright 1991 by Rob Elliott. All rights reserved.\n");
- printf("May be freely distributed. Pardon the lousy interface ...\n\n");
- printf("Select a font in text format to be converted (cancel to quit):\n");
-
- infilenum = getinfile(filename);
- if (infilenum) {
- printf("Select a filename for the font in resource format:\n");
- outfilenum = getoutfile(filename);
-
- if (outfilenum) {
- printf("Converting ...\n");
- cvt();
- CloseResFile(outfilenum);
- }
- else
- return;
- FSClose(infilenum);
- }
- else
- return;
- }
- }
-